package com.example.hospitalsystem.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.hospitalsystem.mapper.UserMapper;
import com.example.hospitalsystem.pojo.dto.auth.*;
import com.example.hospitalsystem.pojo.entity.User;
import com.example.hospitalsystem.pojo.vo.LoginVo;
import com.example.hospitalsystem.result.Result;
import com.example.hospitalsystem.result.ResultCodeEnum;
import com.example.hospitalsystem.service.AuthService;
import com.example.hospitalsystem.utils.JwtHelper;
import com.example.hospitalsystem.utils.MD5Util;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Objects;

import static com.example.hospitalsystem.utils.EmailConstant.*;


@Service
public class AuthServiceImpl extends ServiceImpl<UserMapper,User>
        implements AuthService {

    @Autowired
    private UserMapper userMapper;


    @Autowired
    private MD5Util md5Util;

    @Autowired
    private JwtHelper jwtHelper;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private HttpServletRequest request;

    @Override
    @Transactional
    public Result<Object> userRegiister(RegisterDto registerDto) {

        if(!Objects.equals(registerDto.getPassword(),registerDto.getResetPassword())){
            return Result.build(null,500,"密码不一致");
        }

        LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(User::getUsername,registerDto.getUsername());
        User getUser=this.getOne(lambdaQueryWrapper);
        if(getUser!=null){
            return Result.build(null, ResultCodeEnum.USERNAME_USED);
        }
        User user=new User();
        BeanUtils.copyProperties(registerDto,user);
        userMapper.insert(user);
//        UserRole userRole = new UserRole();
//        BeanUtils.copyProperties(registerDto, userRole);
//        userRole.setUserId(user.getUserId());
//        userRoleMapper.insert(userRole);

        return Result.build(null,200,"注册账号成功");
    }

    @Transactional
    @Override
    public Result<LoginVo> userLogin(LoginDto loginDto) {

        //首先判断是否有这个账号
        LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUsername,loginDto.getUsername());
        User user=this.getOne(lambdaQueryWrapper);
        if(user==null){
            return Result.build(null,ResultCodeEnum.USER_ERROR);
        }
        //比较密码是否相同
        if(!Objects.equals(user.getPassword(),loginDto.getPassword())){
            return Result.build(null,ResultCodeEnum.PASSWORD_ERROR);
        }
        LoginVo loginVo=new LoginVo();
        System.out.println("userId为："+user.getUserId());
        loginVo.setToken(jwtHelper.createToken(user.getUserId(), user.getRole()));
        System.out.println("登录的角色role: "+jwtHelper.getRole(loginVo.getToken()));
        return Result.build(loginVo,200,"登录成功");
    }

    @Override
    public Result<Object> loginByEmail(EmailCaptchaDto emailCaptchaDto) {

        //账号查询
        LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getEmail,emailCaptchaDto.getEmail());
        User user=this.getOne(lambdaQueryWrapper);

        if(user==null){
            return Result.build(null,ResultCodeEnum.USER_ERROR);
        }
        String captcha=(String) redisTemplate.opsForValue().get(EMAIL_LOGIN_PRIM+emailCaptchaDto.getEmail());
        //账号密码判断
        if (captcha != null && !StringUtils.isEmpty(emailCaptchaDto.getCaptcha()) && captcha.equalsIgnoreCase(emailCaptchaDto.getCaptcha())) {
            //验证码正确
            //根据用户id生成token
            LoginVo loginVo=new LoginVo();
            loginVo.setToken(jwtHelper.createToken(user.getUserId(), user.getRole()));
            return Result.ok(loginVo);
        }else{
            return Result.build(null,ResultCodeEnum.CAPTCHA_ERROR);
        }
    }

    @Override
    public Result<Object> changePwdByPast(ChangePwd changePwd) {

        String token=request.getHeader("Authorization");

        int userId=jwtHelper.getUserId(token);

        LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUserId,userId);

        User user=this.getOne(lambdaQueryWrapper);
        if(user==null){
            return Result.build(null,ResultCodeEnum.USER_ERROR);
        }

        //判断原始密码是否正确
        if(!user.getPassword().equalsIgnoreCase(changePwd.getPassword())){
            return Result.build(null,"原密码错误，请重新输入密码");
        }
        user.setPassword(changePwd.getNewPassword());
        boolean T= this.updateById(user);
        if(!T){
            return Result.build(null,200,"修改密码失败");
        }
        return Result.build(null,200,"修改密码成功");
    }

    @Override
    public Result<Object> bindEmail(EmailCaptchaDto emailCaptchaDto) {

        String token=request.getHeader("Authorization");
        int userId=jwtHelper.getUserId(token);
        LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUserId,userId);
        User user=this.getOne(lambdaQueryWrapper);
        if(StringUtils.hasLength(user.getEmail())){
            return Result.build(null,ResultCodeEnum.EMAIL_USED);
        }
        //判断验证码是否相同
        String captcha= (String) redisTemplate.opsForValue().get(EMAIL_BINDING_EM_PRIM+emailCaptchaDto.getEmail());
        if(captcha!=null&& !StringUtils.isEmpty(emailCaptchaDto.getCaptcha())&& captcha.equalsIgnoreCase(emailCaptchaDto.getCaptcha())){
            LambdaUpdateWrapper<User> lambdaUpdateWrapper=new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(User::getUserId,userId)
                    .set(User::getEmail,emailCaptchaDto.getEmail());

            this.update(lambdaUpdateWrapper);

            return Result.build(null,200,"邮箱绑定成功");
        }

        return Result.build(null,ResultCodeEnum.CAPTCHA_ERROR);
    }

    @Override
    public Result<Object> changePwdByEmail(ChangePwdByEmailDto changePwdByEmailDto) {
        if(!isEmailExist(changePwdByEmailDto.getEmail())){
            return Result.build(null,ResultCodeEnum.LOGIN_EMAIL_ERROR);
        }

        String token= request.getHeader("Authorization");
        int userId=jwtHelper.getUserId(token);
        LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUserId,userId);
        User user=this.getOne(lambdaQueryWrapper);

        //判断验证码是否相同
        String captcha=(String) redisTemplate.opsForValue().get(EMAIL_CHANGE_PW_PRIM+changePwdByEmailDto.getEmail());

        if(captcha!=null&&!StringUtils.isEmpty(changePwdByEmailDto.getCaptcha())&&captcha.equalsIgnoreCase(changePwdByEmailDto.getCaptcha())){
            LambdaUpdateWrapper<User> lambdaUpdateWrapper=new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(User::getUserId,userId)
                    .set(User::getPassword,changePwdByEmailDto.getNewPassword());
            this.update(lambdaUpdateWrapper);
            return Result.build(null,200,"通过邮箱修改密码成功");

        }
        return Result.build(null,ResultCodeEnum.CAPTCHA_ERROR);
    }

    @Override
    public Result<Object> verifyOldEmail(EmailCaptchaDto emailCaptchaDto) {

        String token=request.getHeader("Authorization");
        int userId= jwtHelper.getUserId(token);

        LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUserId,userId);
        User user=this.getOne(lambdaQueryWrapper);

        if(!user.getEmail().equalsIgnoreCase(emailCaptchaDto.getEmail())){
            return Result.build(null,"邮箱输入错误");
        }
        String captcha=(String) redisTemplate.opsForValue().get(EMAIL_CHANGE_EM_OLD_PRIM+emailCaptchaDto.getEmail());
        if (captcha != null && !StringUtils.isEmpty(captcha) && captcha.equalsIgnoreCase(emailCaptchaDto.getCaptcha())) {
            return Result.build(null,200,"旧邮箱验证成功");
        }
        return Result.build(null,ResultCodeEnum.CAPTCHA_ERROR);
    }

    @Override
    public Result<Object> changeEmail(ChangeEmailDto changeEmailDto) {

        String token=request.getHeader("Authorization");
        int userId= jwtHelper.getUserId(token);

        LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUserId,userId);

        User user=this.getOne(lambdaQueryWrapper);
        if(!user.getEmail().equalsIgnoreCase(changeEmailDto.getOldEmail())){
            return Result.build(null,"旧邮箱输入错误，请输入正确邮箱");
        }

        String captcha=(String) redisTemplate.opsForValue().get(EMAIL_CHANGE_EM_NEW_PRIM+changeEmailDto.getNewEmail());
        if(captcha!=null&& !StringUtils.isEmpty(changeEmailDto.getCaptcha())&&captcha.equalsIgnoreCase(changeEmailDto.getCaptcha())){
            LambdaUpdateWrapper<User> lambdaUpdateWrapper=new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(User::getUserId,userId)
                    .set(User::getEmail,changeEmailDto.getNewEmail());

            this.update(lambdaUpdateWrapper);
            return Result.build(null,200,"邮箱绑定成功");
        }

        return Result.build(null,ResultCodeEnum.CAPTCHA_ERROR);
    }

    @Override
    public Result<Object> cancelEmailBind(CancelEmailDto cancelEmailDto) {
        String token=request.getHeader("Authorization");
        int userId= jwtHelper.getUserId(token);

        LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUserId,userId);

        User user=this.getOne(lambdaQueryWrapper);
        if(!user.getEmail().equalsIgnoreCase(cancelEmailDto.getOldEmail())){
            return Result.build(null,"旧邮箱输入错误，请输入正确邮箱");
        }

        String captcha=(String) redisTemplate.opsForValue().get(EMAIL_CHANGE_EM_OLD_PRIM+cancelEmailDto.getOldEmail());
        if(captcha!=null&& !StringUtils.isEmpty(cancelEmailDto.getCaptcha())&&captcha.equalsIgnoreCase(cancelEmailDto.getCaptcha())){
            LambdaUpdateWrapper<User> lambdaUpdateWrapper=new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(User::getUserId,userId)
                    .set(User::getEmail,"");

            this.update(lambdaUpdateWrapper);
            return Result.build(null,200,"解绑邮箱成功");
        }

        return Result.build(null,ResultCodeEnum.CAPTCHA_ERROR);
    }

    private boolean isEmailExist(String emial){
        LambdaQueryWrapper<User> lambdaUpdateWrapper=new LambdaQueryWrapper<>();
        lambdaUpdateWrapper.eq(User::getEmail,emial);
        return userMapper.exists(lambdaUpdateWrapper);
    }
}
